package com.sec.android.app.myfiles.module;

import com.sec.android.app.myfiles.module.abstraction.AbsModuleLoaderImp;
import com.sec.android.app.myfiles.module.abstraction.AbsModuleManager;
import com.sec.android.app.myfiles.module.cloud.CloudFileModuleLoaderImp;
import com.sec.android.app.myfiles.module.download.DownloadModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.blank.BlankModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.category.CategoryModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.file.LocalFileModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.foldertree.FolderTreeModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.home.HomeModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.recent.RecentModuleLoaderImp;
import com.sec.android.app.myfiles.module.local.securelocal.SecureLocalFileModuleLoaderImp;
import com.sec.android.app.myfiles.module.manager.AfwModuleManager;
import com.sec.android.app.myfiles.module.manager.KnoxModuleManager;
import com.sec.android.app.myfiles.module.manager.MassModuleManager;
import com.sec.android.app.myfiles.module.manager.PhoneModuleManager;
import com.sec.android.app.myfiles.module.manager.SuggestionModuleManager;
import com.sec.android.app.myfiles.module.manager.TabletModuleManager;
import com.sec.android.app.myfiles.module.optimizestorage.OptimizeStorageModuleLoaderImp;
import com.sec.android.app.myfiles.module.preview.PreviewCompressModuleLoaderImp;
import com.sec.android.app.myfiles.module.trash.TrashFileModuleLoaderImp;
import com.sec.android.app.myfiles.module.search.SearchModuleLoaderImp;
import com.sec.android.app.myfiles.module.sfinder.SFinderModuleLoaderImp;
import com.sec.android.app.myfiles.module.shortcut.ShortcutModuleLoaderImp;
import com.sec.android.app.myfiles.module.suggestion.SuggestionModuleLoaderImp;
import com.sec.android.app.myfiles.util.chain.ChainBuilder;

public class ModuleManager {

    public static final int RECENT_MODULE = 0x1;
    public static final int LOCAL_FILE_MODULE = 0x2;
    public static final int CATEGORY_MODULE = 0x4;
    public static final int HOME_MODULE = 0x8;
    public static final int SEARCH_MODULE = 0x10;
    public static final int DOWNLOAD_MODULE = 0x20;
    public static final int CLOUD_FILE_MODULE = 0x40;
    public static final int SHORTCUT_MODULE = 0x80;
    public static final int SFINDER_MODULE = 0x100;
    public static final int PREVIEW_COMPRESS_MODULE = 0x200;
    public static final int SUGGESTION_MODULE = 0x400;
    public static final int OPTIMIZE_STORAGE_MODULE = 0x800;
    public static final int TRASH_FILE_MODULE = 0x1000;
    public static final int SECURE_LOCAL_FILE_MODULE = 0x2000;

    public static final int TABLET_MODULE = 0x10000;

    public static final int ALL_MODULE = RECENT_MODULE |
            LOCAL_FILE_MODULE |
            SECURE_LOCAL_FILE_MODULE |
            CATEGORY_MODULE |
            HOME_MODULE |
            SEARCH_MODULE |
            DOWNLOAD_MODULE |
            CLOUD_FILE_MODULE |
            SHORTCUT_MODULE |
            SFINDER_MODULE |
            PREVIEW_COMPRESS_MODULE |
            TABLET_MODULE |
            SUGGESTION_MODULE |
            OPTIMIZE_STORAGE_MODULE |
            TRASH_FILE_MODULE;

    private static ModuleManager mSelf;
    private AbsModuleManager mModuleManager;
    private AbsModuleLoaderImp mModuleLoader = null;

    private ModuleManager() {
        ChainBuilder<AbsModuleManager> builder = new ChainBuilder<>().
                append(new AfwModuleManager()).
                append(new KnoxModuleManager()).
                append(new MassModuleManager()).
                append(new PhoneModuleManager()).
                append(new TabletModuleManager()).
                append(new SuggestionModuleManager());

        mModuleManager = builder.getInstance();
    }

    public static ModuleManager getModuleManager() {
        if (mSelf == null) {
            mSelf = new ModuleManager();
        }
        return mSelf;
    }

    public AbsModuleLoaderImp getModules() {
        if (mModuleLoader == null) {
            int moduleList = mModuleManager.getModuleList(ALL_MODULE);
            mModuleLoader = makeModuleChain(moduleList);
        }
        return mModuleLoader;
    }

    private AbsModuleLoaderImp makeModuleChain(int moduleList) {
        ChainBuilder<AbsModuleLoaderImp> chainBuilder = new ChainBuilder<>();

        if ((moduleList & DOWNLOAD_MODULE) > 0) {
            chainBuilder.append(new DownloadModuleLoaderImp());
        }
        if ((moduleList & RECENT_MODULE) > 0) {
            chainBuilder.append(new RecentModuleLoaderImp());
        }
        if ((moduleList & LOCAL_FILE_MODULE) > 0) {
            chainBuilder.append(new LocalFileModuleLoaderImp());
        }
        if ((moduleList & CATEGORY_MODULE) > 0) {
            chainBuilder.append(new CategoryModuleLoaderImp());
        }
        if ((moduleList & HOME_MODULE) > 0) {
            chainBuilder.append(new HomeModuleLoaderImp());
        }
        if ((moduleList & SEARCH_MODULE) > 0) {
            chainBuilder.append(new SearchModuleLoaderImp());
        }
        if ((moduleList & CLOUD_FILE_MODULE) > 0) {
            chainBuilder.append(new CloudFileModuleLoaderImp());
        }
        if ((moduleList & SECURE_LOCAL_FILE_MODULE) > 0) {
            chainBuilder.append(new SecureLocalFileModuleLoaderImp());
        }
        if ((moduleList & SHORTCUT_MODULE) > 0) {
            chainBuilder.append(new ShortcutModuleLoaderImp());
        }
        if ((moduleList & SFINDER_MODULE) > 0) {
            chainBuilder.append(new SFinderModuleLoaderImp());
        }
        if ((moduleList & PREVIEW_COMPRESS_MODULE) > 0) {
            chainBuilder.append(new PreviewCompressModuleLoaderImp());
        }
        if ((moduleList & TABLET_MODULE) > 0) {
            chainBuilder.append(new FolderTreeModuleLoaderImp());
            chainBuilder.append(new BlankModuleLoaderImp());
        }
        if ((moduleList & SUGGESTION_MODULE) > 0) {
            chainBuilder.append(new SuggestionModuleLoaderImp());
        }
        if ((moduleList & OPTIMIZE_STORAGE_MODULE) > 0) {
            chainBuilder.append(new OptimizeStorageModuleLoaderImp());
        }
        if ((moduleList & TRASH_FILE_MODULE) > 0) {
            chainBuilder.append(new TrashFileModuleLoaderImp());
        }
        return chainBuilder.getInstance();
    }
}
